const fs = require('fs')
const http = require('http')
const formidable = require('formidable')
const uuid = require('uuid/v1')
const debug = true
/**
 * @description 处理字符串
 * @param str
 */
exports.parseURL = function parseURL (str) {
    const json = {}
    const key = ['?', '&', '=']
    if (!!str && typeof str === 'string') {
        const cur = str.split(key[0])
        if (cur && cur[1] !== undefined) {
            str.split(key[0])[1].split(key[1]).forEach(function (item) {
                const current = item.split(key[2])
                json[current[0]] = current[1]
            })
        }
    } return json
}

/**
 * @description 主入口
 * @param config
 * @returns {Promise<any>}
 */
exports.listen = function main (config, callBack) {
    const setConfig = config || {}
    const imageUrlRegexp = /\/file\/image\/([\w-\W]+)\.(png|jpeg|jpg|gif)$/
    http.createServer(function (req, res) {
        if (req.url === '/favicon.ico') {
            res.end('')
        } else if (setConfig.useStatic && req.url.match(imageUrlRegexp) !== null) {
            const match = req.url.match(imageUrlRegexp)
            const filename = match[1]
            const filetype = match[2]
            res.writeHead(200, { 'Content-Type': `image/${filetype}` })
            try {
                res.end(    fs.readFileSync(`${setConfig.staticPath}/${filename}.${filetype}`))
            } catch (e) {
                res.end(JSON.stringify({message: '读取资源错误！'}))
            }
        } else {
            callBack(req, res)
        }
    }).listen(setConfig.port || 8080)
}

/**
 * @description 获取query
 * @param url
 * @returns {{}}
 */
exports.getQueryData = function getQueryData (url) {
    return exports.parseURL(url)
}

exports.setPagination = function setPagination (cp, ps) {
    let currentPage = 1
    let pageSize = 10
    if (cp) {
        currentPage = parseInt(cp)
        if (currentPage <= 0) {
            currentPage = 1
        }
    }
    if (ps) {
        pageSize = parseInt(ps)
        if (pageSize <= 0) {
            pageSize = 1
        }
    }
    return {
        currentPage: currentPage,
        pageSize: pageSize,
    }
}

/**
 * @description 获取body
 * @param req
 */
exports.getBodyData = function getBodyData (req) {
    return new Promise(function (resolve, reject) {
        const form = new formidable.IncomingForm(req.url)
        form.parse(req,function (err, fields) {
            if (err) throw err
            resolve (fields)
        })
    })
}

/**
 * @description 获取文件流
 * @param req
 * @returns {Promise<any>}
 */
exports.getFileStream = function getFileStream (req) {
    return new Promise(function (resolve, reject) {
        const form = new formidable.IncomingForm(req.url)
        form.parse(req,function (err, fields, files) {
            if (err) throw err
            resolve (files)
        })
    })
}

/**
 * @description 图片处理
 * @type {{isImage: (function(*=): boolean), isImageFile: (function(*=): boolean), matchImageMType: (function(*): string), imageMType: string[], imageType: string[]}}
 */
exports.image = {
    isImage: function isImage (typeStr) {
        return this.imageType.includes(typeStr)
    },
    isImageFile: function isImageFile (typeStr) {
        return this.imageMType.includes(typeStr)
    },
    isImageSuffix: function isImageSuffix (typeStr) {
      return !/\.(png|jpg|jpeg)$/.test(typeStr)
    },
    matchImageMType: function (typeStr) {
        const match = typeStr.match(/\/(jpg|png|jpeg|gif)/)
        let type = ''
        if (match !== null && !!match[1]) {
            type = match[1]
        } return type
    },
    imageType: ['jpg', 'jpeg', 'png', 'gif'],
    imageMType: ['image/gif', 'image/png', 'image/jpeg', 'image/jpg'],

}

/**
 * @description base64转buffer
 * @param base64
 */
exports.parseBase64ForBuffer = function parseBase64ForBuffer (base64) {
    let data = {}
    if (typeof base64 === 'string') {
        const match = base64.match(/^data:(\w+\/[\w-\W]+);base64,/)
        if (match !== undefined) {
            const type = match[1]
            const base64Data = base64.replace(/^data:image\/\w+;base64,/, "")
            data = {
                type: type,
                name: uuid(),
                size: exports.getBase64Size(base64Data),
                buffer: Buffer.from(base64Data, 'base64')
            }
        }
    } return data
}

/**
 * @description 获取base64大小
 * @param base64
 * @returns {number}
 */
exports.getBase64Size = function getBase64Size (base64) {
    let size = 0
    if (typeof base64 === 'string') {
        const strLength = base64.length
        const fileLength = parseInt(strLength - (strLength / 8) * 2)
        size = (fileLength).toFixed(2)
    } return parseInt(size)
}

/**
 * @description 二进制转buffer
 * @param obj
 * @returns {Promise<any>}
 */
exports.parseBinaryForBuffer = function parseBinaryForBuffer (obj) {
    return new Promise(function (resolve, reject) {
        if (obj !== null && obj.path !== undefined && typeof obj.path === 'string') {
            fs.readFile(obj.path, function (err, data) {
                if (err) throw err
                resolve({
                    type: obj.type,
                    name: uuid(),
                    size: obj.size,
                    buffer: data
                })
            })
        }
    })
}

/**
 * @description 空对象检查
 * @param v
 * @returns {boolean}
 */
exports.isEmptyObject = function isEmptyObject (v) {
    if (v !== null && typeof v === 'object') {
        for (let item in v) {
            return true
        }
    } return false
}

/**
 * @description 设置头部
 * @param res
 * @param config
 */
exports.setHeaders = function setHeaders (res, config) {
    if (config !== null && typeof config === 'object') {
        res.writeHead(200, 'OK', config)
    }
}

/**
 * @description
 * @param callBack
 * @param req
 * @param res
 */
exports.bindModule = function bindModule (callBack, req, res) {
    res.outPrintJSON = exports.outPrintJSON
    /**
     * @description 输出警告
     * @param message
     */
    res.outPrintWarn = function outPrintJSON (message) {
        res.end(exports.outPrintJSON({ code: 400, message: message || '' }))
    }
    /**
     * @description 输出错误
     * @param message
     */
    res.outPrintError = function outPrintJSON (message) {
        res.end(exports.outPrintJSON({ code: 500, message: message || '' }))
    }
    /**
     * @description 输出严重错误
     * @param message
     */
    res.outPrintDanger = function outPrintJSON (message) {
        res.end(exports.outPrintJSON({ code: 300, message: message || '' }))
    }
    /**
     * @description 输出数据
     * @param data
     * @param message
     */
    res.outPrintData = function outPrintJSON (data, message) {
        res.end(exports.outPrintJSON({ code: 200, data: data || {}, message: message || '' }))
    }
    /**
     * @description 全局属性方法
     * @type {{request: *, setHeaders: *, image: ({isImage: (function(*=): boolean), isImageFile: (function(*=): boolean), matchImageMType: (function(*): string), imageMType: string[], imageType: string[]}|string|SVGImageElement), outPrintJSON: *, parseBase64ForBuffer: *, isEmptyObject: *, type: *, getBodyData: *, url: *, getQueryData: *, parseURL: (*|Morxv.parseURL), getFileStream: *, getBase64Size: *, response: *, parseBinaryForBuffer: *, getAbsoluteURL: *}}
     */
    const global = {
        response: res,
        request: req,
        url: req.url,
        type: req.type,
        setHeaders: exports.setHeaders,
        isEmptyObject: exports.isEmptyObject,
        image: exports.image,
        /**
         * @description 解析二进制为buffer
         */
        parseBinaryForBuffer: exports.parseBinaryForBuffer,
        /**
         * @description 获取base64的大小(byte)
         */
        getBase64Size: exports.getBase64Size,
        /**
         * @description 解析base64为buffer
         */
        parseBase64ForBuffer: exports.parseBase64ForBuffer,
        /**
         * @description 获取文件流
         */
        getFileStream: exports.getFileStream,
        /**
         * @description 获取请求的body数据
         */
        getBodyData: exports.getBodyData,
        /**
         * @description 获取URL的query数据
         */
        getQueryData: exports.getQueryData,
        /**
         * @description 解析URL为Object
         */
        parseURL: exports.parseURL,
        /**
         * @description 获取绝对路径
         */
        getAbsoluteURL: exports.getAbsoluteURL,
        /**
         * @description 输出JSON
         */
        outPrintJSON: exports.outPrintJSON,
        isDef: exports.isDef,
        isUnDef: exports.isUnDef,
        setPagination: exports.setPagination
    }
    if (typeof callBack === 'function') {
        callBack.call(global)
    }
}

exports.isDef = function isDef (v) {
    return v !== null && v !== undefined && v !== 'null' && v !== 'undefined'
}

exports.isUnDef = function isUndef (v) {
    return v === null || v === undefined || v === 'null' || v === 'undefined'
}

/**
 * @description 获取URL
 * @param urlStr
 * @returns {string}
 */
exports.getAbsoluteURL = function getAbsoluteURL (urlStr) {
    let str = ''
    if (typeof urlStr === 'string') {
        str = urlStr.split(/(\?|\&)/)[0]
    } return str
}

/**
 * @description
 * @param data
 * @returns {string}
 */
exports.outPrintJSON = function outPrintJSON (any) {
    try {
        if (!!debug) {
            console.log(any)
        }
        return JSON.stringify(any)
    } catch (e) {
        console.log(e)
    }
}